package com.ygqh.baby.controller.mobile;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.ygqh.baby.exception.YgException;
import com.ygqh.baby.po.YgUserAddress;
import com.ygqh.baby.redis.RedisDao;
import com.ygqh.baby.service.*;
import org.apache.log4j.Logger;
import org.crazycake.shiro.SerializeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fasterxml.jackson.databind.util.JSONPObject;
import com.ygqh.baby.ao.AppType;
import com.ygqh.baby.ao.CodeType;
import com.ygqh.baby.ao.Message;
import com.ygqh.baby.ao.OrderStatus;
import com.ygqh.baby.ao.PayType;
import com.ygqh.baby.po.YgOrder;
import com.ygqh.baby.po.YgUser;
import com.ygqh.baby.service.alipay.util.AlipayNotify;
import com.ygqh.baby.service.alipay.util.AlipaySubmit;
import com.ygqh.baby.service.impl.DocumentConstant;
import com.ygqh.baby.utils.SessionUtil;

/**
 * 
 * @author guohao
 *
 */
@Controller
@RequestMapping("/mobile/alipay")
public class YgAlipayController {
	protected final Logger logger = Logger.getLogger(this.getClass());
	@Autowired
	private YgOrderService orderService;
	@Autowired
	private YgOrderPaymentService orderPaymentService;
	@Autowired
	private YgFrameCodeService ygFrameCodeService;
	@Autowired
	private YgAccountDetailService ygAccountDetailService;
	@Autowired
	private AlipayNotify AlipayNotify;
	@Autowired
	private AlipaySubmit AlipaySubmit;
	@Value("${alipay.partner}")
	private String partner;
	@Value("${alipay.seller_id}")
	private String sellerId;
	@Value("${alipay.key}")
	private String key;
	@Value("${alipay.notify_url}")
	private String notify_url;
	@Value("${alipay.return_url}")
	private String return_url;
	@Value("${alipay.recharge.notify_url}")
	private String recharge_notify_url;
	@Value("${alipay.recharge.return_url}")
	private String recharge_return_url;
	@Value("${alipay.payment_type}")
	private String payment_type;
	@Value("${alipay.sign_type}")
	private String sign_type;
	@Value("${alipay.api}")
	private String api;
	@Value("${alipay.charset}")
	private String charset;
	@Value("${alipay.gatewayUrl}")
	private String gatewayUrl;
	@Value("${alipay.refund.service}")
	private String refundService;
	@Autowired
	private DocumentConstant documentConstant;
	@Autowired
	private YgOrderLogService ygOrderLogService;
	@Autowired
	private YgCardCouponDetailService ygCardCouponDetailService;
	@Autowired
	private RedisDao redisDao;
	@Autowired
	private YgOrderDetailService ygOrderDetailService;
	@Autowired
	private YgOrderService ygOrderService;
	@Value("${trustoner.supplier.id}")
	private Long TRUSTONE_SUPPLIER_ID;

	@RequestMapping(value = "toAlipayIndex", method = RequestMethod.GET)
	public String toAlipayIndex(Model model) {
		List<YgOrder> list = orderService.find();
		Long orderId = 1l;
		for (YgOrder order : list) {
			orderId = order.getOrderId();
			break;
		}
		model.addAttribute("orderId", orderId);
		return "alipayindex";
	}

	@RequestMapping(value = "toAlipayApi", method = RequestMethod.GET)
	@ResponseBody
	public JSONPObject toAlipayApi(String state, HttpServletRequest request, HttpServletResponse out, String callback) throws UnsupportedEncodingException {
		out.setHeader("Content-type", "text/html;charset=UTF-8");
		out.setCharacterEncoding("UTF-8");

		// ////////////////////////////////////////////////////////////////////////////////

		// 生成支付流水
		String[] str = state.split("-");
		
		Boolean existSupplierGoods = ygOrderDetailService.existSupplierGoods(Long.parseLong(str[0]),TRUSTONE_SUPPLIER_ID);
		
		if(existSupplierGoods){
			return  new JSONPObject(callback, Message.error("支付宝暂不支持跨境商品，请到微信商城支付。", null));
		}
		Long paymentCode = ygFrameCodeService.getFrameCode(CodeType.OrderPM, new Date());
		orderPaymentService.addPaymentRecord(str[0], new BigDecimal(str[1]), paymentCode.toString(), PayType.Alipay, AppType.WeChat);

		// 把请求参数打包成数组
		Map<String, String> sParaTemp = new HashMap<String, String>();
		sParaTemp.put("service", api);
		sParaTemp.put("partner", partner);
		sParaTemp.put("seller_id", sellerId);
		sParaTemp.put("_input_charset", charset);
		sParaTemp.put("payment_type", payment_type);
		sParaTemp.put("notify_url", notify_url);
		sParaTemp.put("return_url", return_url + "?state=" + state);
		sParaTemp.put("out_trade_no", paymentCode.toString());
		sParaTemp.put("subject", "壹果订单");
		sParaTemp.put("total_fee", str[1]);
		sParaTemp.put("show_url", "");
		// sParaTemp.put("app_pay","Y");//启用此参数可唤起钱包APP支付。
		sParaTemp.put("body", "壹果订单");
		// 其他业务参数根据在线开发文档，添加参数.文档地址:https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.2Z6TSk&treeId=60&articleId=103693&docType=1
		// 如sParaTemp.put("参数名","参数值");
		// 建立请求
		String sHtmlText = AlipaySubmit.buildRequest(sParaTemp, "post", "确认");
		return new JSONPObject(callback, Message.success(documentConstant.MESSAGE_SUCCESS, sHtmlText));

	}

	@RequestMapping(value = "returnUrl")
	@ResponseBody
	public JSONPObject returnUrl(HttpServletRequest request, HttpServletResponse out, String callback) throws IOException {
		out.setHeader("Content-type", "text/html;charset=UTF-8");
		// 这句话的意思，是告诉servlet用UTF-8转码，而不是用默认的ISO8859
		out.setCharacterEncoding("UTF-8");
		// String paramss = new
		// String(request.getParameter("params").getBytes("ISO-8859-1"),
		// "UTF-8");
		// 获取支付宝GET过来反馈信息
		Map<String, String> params = new HashMap<String, String>();
		Map requestParams = request.getParameterMap();
		logger.info(requestParams.toString());
		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}
			// 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
			/*
			 * valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
			 */
			params.put(name, valueStr);
		}

		// 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
		// 商户订单号
		String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
		// 支付宝交易号
		String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
		// 交易状态
		String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
		String total_fee = new String(request.getParameter("total_fee").getBytes("ISO-8859-1"), "UTF-8");
		// 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
		// 计算得出通知验证结果
		boolean verify_result = AlipayNotify.verify(params);
		if (verify_result) {// 验证成功
			// ////////////////////////////////////////////////////////////////////////////////////////
			// 请在这里加上商户的业务逻辑程序代码

			// ——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
			if (trade_status.equals("TRADE_SUCCESS")) {
				// 判断该笔订单是否在商户网站中已经做过处理
				// 如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
				// 如果有做过处理，不执行商户的业务程序
				orderService.doBussness4PaySuccess(out_trade_no, trade_no, new BigDecimal(total_fee), AppType.WeChat, PayType.Alipay);
			}

			// 该页面可做页面美工编辑
			// out.getWriter().println(headerString + "<br />");
			// ——请根据您的业务逻辑来编写程序（以上代码仅作参考）——

			// ////////////////////////////////////////////////////////////////////////////////////////
			return new JSONPObject(callback, Message.success(documentConstant.MESSAGE_SUCCESS, "验证成功"));
		} else {
			// 该页面可做页面美工编辑
			// out.getWriter().println(headerString);
			return new JSONPObject(callback, Message.error(documentConstant.MESSAGE_ERROR, "验证失败"));
		}

	}

	@RequestMapping(value = "notifyUrl")
	public void notifyUrl(HttpServletRequest request, HttpServletResponse out) throws IOException {
		Map<String, String> params = new HashMap<String, String>();
		Map<String, String[]> requestParams = request.getParameterMap();
		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}
			// 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
			/*
			 * valueStr = new String(valueStr.getBytes("ISO-8859-1"), "UTF-8");
			 */
			params.put(name, valueStr);
		}
		logger.info(params.toString());

		// 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
		// 商户订单号
		String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
		// 支付宝交易号
		String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
		// 交易状态
		String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
		// 交易金额
		String total_fee = new String(request.getParameter("total_fee").getBytes("ISO-8859-1"), "UTF-8");
		// 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
		String result = "success";

		if (AlipayNotify.verify(params)) {// 验证成功
			// ////////////////////////////////////////////////////////////////////////////////////////
			try {
				if (trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")) {
					// 拆单 回写支付流水,同步订单
					orderService.doBussness4PaySuccess(out_trade_no, trade_no, new BigDecimal(total_fee), AppType.WeChat, PayType.Alipay);
				}
			} catch (Exception e) {
				result = "false";
				e.printStackTrace();
			}
			// ——请根据您的业务逻辑来编写程序（以下代码仅作参考）——

			logger.debug("支付宝异步回调验证成功===============out_trade_no :" + out_trade_no + "===========");
			out.getWriter().print(result); // 请不要修改或删除
			System.out.println("notifyUrl==========" + result);

			// return result;
		} else {// 验证失败
			logger.error("支付宝异步回调验证失败===============out_trade_no :" + out_trade_no + "===========");
			System.out.println("notifyUrl==========" + result);
			out.getWriter().print(result);
			// return result;
		}

	}

	@RequestMapping(value = "rechargeByAli", method = RequestMethod.GET)
	@ResponseBody
	public JSONPObject rechargeByAli(BigDecimal rechargePrice, HttpServletRequest request, HttpServletResponse out, String callback)
			throws UnsupportedEncodingException {
		YgUser user = SessionUtil.getCurrentUser();
		out.setHeader("Content-type", "text/html;charset=UTF-8");
		out.setCharacterEncoding("UTF-8");

		// ////////////////////////////////////////////////////////////////////////////////

		// 生成支付流水
		Long paymentCode = ygFrameCodeService.getFrameCode(CodeType.RechargePM, new Date());
		ygOrderLogService.addOrderLog(paymentCode, OrderStatus.WaitingPay, user.getUserName(),
				"用户账户充值：rechargePrice=" + rechargePrice + ";PayType=" + PayType.Alipay);
		// 把请求参数打包成数组
		Map<String, String> sParaTemp = new HashMap<String, String>();
		sParaTemp.put("service", api);
		sParaTemp.put("partner", partner);
		sParaTemp.put("seller_id", sellerId);
		sParaTemp.put("_input_charset", charset);
		sParaTemp.put("payment_type", payment_type);
		sParaTemp.put("notify_url", recharge_notify_url);
		sParaTemp.put("return_url", recharge_return_url + "?state=" + paymentCode + "-" + PayType.Alipay);
		sParaTemp.put("out_trade_no", paymentCode.toString());
		sParaTemp.put("subject", "壹果充值");
		sParaTemp.put("total_fee", rechargePrice.toString());
		sParaTemp.put("show_url", "");
		// sParaTemp.put("app_pay","Y");//启用此参数可唤起钱包APP支付。
		sParaTemp.put("body", user.getId().toString());
		sParaTemp.put("metadata", user.getId().toString());
		// 其他业务参数根据在线开发文档，添加参数.文档地址:https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.2Z6TSk&treeId=60&articleId=103693&docType=1
		// 如sParaTemp.put("参数名","参数值");
		// 建立请求
		String sHtmlText = AlipaySubmit.buildRequest(sParaTemp, "post", "确认");
		return new JSONPObject(callback, Message.success(documentConstant.MESSAGE_SUCCESS, sHtmlText));

	}

	@RequestMapping(value = "rechargeReturnUrl")
	@ResponseBody
	public JSONPObject rechargeReturnUrl(HttpServletRequest request, HttpServletResponse out, String callback) throws IOException {
		out.setHeader("Content-type", "text/html;charset=UTF-8");
		// 这句话的意思，是告诉servlet用UTF-8转码，而不是用默认的ISO8859
		out.setCharacterEncoding("UTF-8");
		YgUser user = SessionUtil.getCurrentUser();
		// String paramss = new
		// String(request.getParameter("params").getBytes("ISO-8859-1"),
		// "UTF-8");
		// 获取支付宝GET过来反馈信息
		Map<String, String> params = new HashMap<String, String>();
		Map requestParams = request.getParameterMap();
		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}
			// 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
			/*
			 * valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
			 */
			params.put(name, valueStr);
		}

		// 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
		// 商户订单号
		String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
		// 支付宝交易号
		String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
		// 交易状态
		String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
		String total_fee = new String(request.getParameter("total_fee").getBytes("ISO-8859-1"), "UTF-8");
		String userId = new String(request.getParameter("body").getBytes("ISO-8859-1"), "UTF-8");
		// 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
		// 计算得出通知验证结果
		boolean verify_result = AlipayNotify.verify(params);
		String result = "验证成功";
		if (verify_result) {// 验证成功
			// ////////////////////////////////////////////////////////////////////////////////////////
			// 请在这里加上商户的业务逻辑程序代码

			// ——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
			if (trade_status.equals("TRADE_SUCCESS")) {
				// 判断该笔订单是否在商户网站中已经做过处理
				// 如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
				// 如果有做过处理，不执行商户的业务程序
				// 添加支付充值流水
				// 校验成功，回写金额
				// 校验成功，回写金额
				ygAccountDetailService.doBussnessForPaySuccess(Long.parseLong(out_trade_no), Long.parseLong(userId), new BigDecimal(total_fee), PayType.Alipay,
						"rechargeReturnUrl");
			}

			// 该页面可做页面美工编辑
			// out.getWriter().println(headerString + "<br />");
			// ——请根据您的业务逻辑来编写程序（以上代码仅作参考）——

			// ////////////////////////////////////////////////////////////////////////////////////////
			return new JSONPObject(callback, Message.success(documentConstant.MESSAGE_SUCCESS, ""));
		} else {
			// 该页面可做页面美工编辑
			result = "验证失败";
			// out.getWriter().println(headerString);
			return new JSONPObject(callback, Message.error(documentConstant.MESSAGE_ERROR, ""));
		}

	}

	@RequestMapping(value = "rechargeNotifyUrl")
	public void rechargeNotifyUrl(HttpServletRequest request, HttpServletResponse out) throws IOException {
		Map<String, String> params = new HashMap<String, String>();
		Map requestParams = request.getParameterMap();
		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}
			// 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
			/*
			 * valueStr = new String(valueStr.getBytes("ISO-8859-1"), "UTF-8");
			 */
			params.put(name, valueStr);
		}

		// 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
		// 商户订单号
		String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
		// 支付宝交易号
		String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
		// 交易状态
		String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
		// 交易金额
		String total_fee = new String(request.getParameter("total_fee").getBytes("ISO-8859-1"), "UTF-8");

		String userId = new String(request.getParameter("body").getBytes("ISO-8859-1"), "UTF-8");
		// 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
		String result = "success";

		if (AlipayNotify.verify(params)) {// 验证成功
			// ////////////////////////////////////////////////////////////////////////////////////////
			try {
				if (trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")) {
					// 校验成功，回写金额
					ygAccountDetailService.doBussnessForPaySuccess(Long.parseLong(out_trade_no), Long.parseLong(userId), new BigDecimal(total_fee),
							PayType.Alipay, "rechargeNotifyUrl");
				}
			} catch (Exception e) {
				result = "false";
				e.printStackTrace();
			}
			// ——请根据您的业务逻辑来编写程序（以下代码仅作参考）——

			logger.debug("支付宝异步回调验证成功===============out_trade_no :" + out_trade_no + "===========");
			out.getWriter().print(result); // 请不要修改或删除
			System.out.println("notifyUrl==========" + result);

			// return result;
		} else {// 验证失败
			logger.debug("支付宝异步回调验证失败===============out_trade_no :" + out_trade_no + "===========");
			System.out.println("notifyUrl==========" + result);
			out.getWriter().print(result);
			// return result;
		}

	}

	private Map<String, String> getAlipayNotifyParam(HttpServletRequest request) {
		Map<String, String> params = new HashMap<String, String>();
		Map<?, ?> requestParams = request.getParameterMap();
		for (Iterator<?> iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}
			// 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
			/*
			 * valueStr = new String(valueStr.getBytes("ISO-8859-1"), "UTF-8");
			 */
			params.put(name, valueStr);
		}
		return params;
	}

	@RequestMapping(value = "toAlipayApiForCard", method = RequestMethod.GET)
	@ResponseBody
	public JSONPObject toAlipayApi(Long cardDetailId, Long orderId, BigDecimal totalPrice, String addrInfo,
								   HttpServletRequest request, HttpServletResponse out, String callback) throws UnsupportedEncodingException {
		out.setHeader("Content-type", "text/html;charset=UTF-8");
		out.setCharacterEncoding("UTF-8");
		// 生成支付流水
		Long paymentCode = ygFrameCodeService.getFrameCode(CodeType.OrderPM, new Date());
		orderPaymentService.addPaymentRecord(orderId.toString(), totalPrice, paymentCode.toString(), PayType.Alipay, AppType.WeChat);
		// 把请求参数打包成数组
		Map<String, String> sParaTemp = new HashMap<String, String>();
		sParaTemp.put("service", api);
		sParaTemp.put("partner", partner);
		sParaTemp.put("seller_id", sellerId);
		sParaTemp.put("_input_charset", charset);
		sParaTemp.put("payment_type", payment_type);
		sParaTemp.put("notify_url", "http://m.yiigoo.com/mobile/alipay/notifyUrlForCard.do");
		String state = orderId + "-" + totalPrice.toString();
		sParaTemp.put("return_url", "http://m.yiigoo.com/order/cardpaysuccess.html?state=" + state);
		sParaTemp.put("out_trade_no", paymentCode.toString());
		sParaTemp.put("subject", "壹果订单");
		sParaTemp.put("total_fee", totalPrice.toString());
		sParaTemp.put("show_url", "");
		// sParaTemp.put("app_pay","Y");//启用此参数可唤起钱包APP支付。
		sParaTemp.put("body", "壹果订单");
		// 其他业务参数根据在线开发文档，添加参数.文档地址:https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.2Z6TSk&treeId=60&articleId=103693&docType=1
		// 如sParaTemp.put("参数名","参数值");
		// 建立请求
		String sHtmlText = AlipaySubmit.buildRequest(sParaTemp, "post", "确认");
		try {
			Map<String, Object> data = new HashMap<>();
			data.put("userId", SessionUtil.getCurrentUser().getId());
			data.put("cardDetailId", cardDetailId);
			data.put("orderId", orderId);
			data.put("totalPrice", totalPrice);
			data.put("addrInfo", addrInfo);
			redisDao.set(("card_payment_ode_" + paymentCode).getBytes(), SerializeUtils.serialize(data), 24 * 60 * 60 * 1000);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		return new JSONPObject(callback, Message.success(documentConstant.MESSAGE_SUCCESS, sHtmlText));
	}

	@RequestMapping(value = "notifyUrlForCard")
	public void notifyUrlForCard(HttpServletRequest request, HttpServletResponse out) throws IOException {
		Map<String, String> params = new HashMap<String, String>();
		Map<String, String[]> requestParams = request.getParameterMap();
		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}
			// 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
			/*
			 * valueStr = new String(valueStr.getBytes("ISO-8859-1"), "UTF-8");
			 */
			params.put(name, valueStr);
		}
		logger.info(params.toString());

		// 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
		// 商户订单号
		String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
		// 支付宝交易号
		String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
		// 交易状态
		String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
		// 交易金额
		String total_fee = new String(request.getParameter("total_fee").getBytes("ISO-8859-1"), "UTF-8");
		// 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
		String result = "success";

		if (AlipayNotify.verify(params)) {// 验证成功
			// ////////////////////////////////////////////////////////////////////////////////////////
			try {
				if (trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")) {
					// 拆单 回写支付流水,同步订单
					orderService.doBussness4PaySuccess(out_trade_no, trade_no, new BigDecimal(total_fee), AppType.WeChat, PayType.Alipay);
					doCardPay(out_trade_no);
				}
			} catch (Exception e) {
				result = "false";
				e.printStackTrace();
			}
			// ——请根据您的业务逻辑来编写程序（以下代码仅作参考）——

			logger.debug("支付宝异步回调验证成功===============out_trade_no :" + out_trade_no + "===========");
			out.getWriter().print(result); // 请不要修改或删除
			System.out.println("notifyUrl==========" + result);

			// return result;
		} else {// 验证失败
			logger.error("支付宝异步回调验证失败===============out_trade_no :" + out_trade_no + "===========");
			System.out.println("notifyUrl==========" + result);
			out.getWriter().print(result);
			// return result;
		}

	}

	private void doCardPay(String paymentCode) {
		try {
			byte[] bytes = redisDao.get(("card_payment_ode_" + paymentCode).getBytes());
			if (bytes != null && bytes.length > 0) {
				Map<String, Object> data = (Map<String, Object>) SerializeUtils.deserialize(bytes);
				String addrInfo = (String) data.get("addrInfo");
				YgUserAddress address = JSON.parseObject(addrInfo, new TypeReference<YgUserAddress>() {
				});
				Long userId = (Long) data.get("userId");
				Long cardDetailId = (Long) data.get("cardDetailId");
				Long orderId = (Long) data.get("orderId");
				BigDecimal totalPrice = (BigDecimal) data.get("totalPrice");
				ygCardCouponDetailService.cashCardByPayExpress(userId, cardDetailId, orderId, totalPrice, AppType.WeChat, PayType.Alipay, address);
				redisDao.del(("card_payment_ode_" + paymentCode).getBytes());
			} else {
				throw new YgException(paymentCode + ":redis信息为空");
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
	}

}
